/*
 * Copyright (c) 2015, the Dart project authors.
 *
 * Licensed under the Eclipse Public License v1.0 (the "License"); you may not use this file except
 * in compliance with the License. You may obtain a copy of the License at
 *
 * http://www.eclipse.org/legal/epl-v10.html
 *
 * Unless required by applicable law or agreed to in writing, software distributed under the License
 * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
 * or implied. See the License for the specific language governing permissions and limitations under
 * the License.
 */
package vm.element

// This file is generated by the script: pkg/vm_service/tool/generate.dart in dart-lang/sdk.

import com.google.gson.JsonArray
import com.google.gson.JsonObject

/**
 * {@link InstanceRef} 是对 {@link Instance} 的引用。
 */
open class InstanceRef(json: JsonObject) : ObjRef(json) {

    /**
     * 与 ReceivePort 分配关联的堆栈跟踪。
     *
     * 为以下实例类型提供：
     *  - ReceivePort
     *
     * 可以返回 <code>null</code>。
     */
    fun getAllocationLocation(): InstanceRef? {
        val obj = json.get("allocationLocation")?.asJsonObject ?: return null
        return InstanceRef(obj)
    }

    /**
     * 实例引用总是包含它们的类。
     */
    open fun getClassRef(): ClassRef {
        return ClassRef(json.get("class").asJsonObject)
    }

    /**
     * 与 Closure 实例关联的上下文。
     *
     * 为以下实例类型提供：
     *  - Closure
     *
     * 可以返回 <code>null</code>。
     */
    open fun getClosureContext(): ContextRef? {
        val obj = json.get("closureContext")?.asJsonObject ?: return null
        val type = json.get("type")?.asString
        if ("Instance" == type || "@Instance" == type) {
            val kind = json.get("kind")?.asString
            if ("Null" == kind) return null
        }
        return ContextRef(obj)
    }

    /**
     * 与 Closure 实例关联的函数。
     *
     * 为以下实例类型提供：
     *  - Closure
     *
     * 可以返回 <code>null</code>。
     */
    open fun getClosureFunction(): FuncRef? {
        val obj = json.get("closureFunction")?.asJsonObject ?: return null
        val type = json.get("type")?.asString
        if ("Instance" == type || "@Instance" == type) {
            val kind = json.get("kind")?.asString
            if ("Null" == kind) return null
        }
        return FuncRef(obj)
    }

    /**
     * 与 ReceivePort 关联的用于调试目的的名称。
     *
     * 为以下实例类型提供：
     *  - ReceivePort
     *
     * 可以返回 <code>null</code>。
     */
    open fun getDebugName(): String? {
        return getAsString("debugName")
    }

    /**
     * 分配给已分配对象的 identityHashCode。此哈希码与 getAllocationTraces() 返回的 HeapSnapshot 和 CpuSample 中提供的哈希码相同。
     */
    open fun getIdentityHashCode(): Int {
        return getAsInt("identityHashCode")
    }

    /**
     * 这是什么类型的实例？
     */
    open fun getKind(): InstanceKind {
        val value = json.get("kind")
        try {
            return if (value == null) InstanceKind.Unknown else InstanceKind.valueOf(value.asString)
        } catch (e: IllegalArgumentException) {
            return InstanceKind.Unknown
        }
    }

    /**
     * The number of (non-static) fields of a PlainInstance, or the length of a List, or the number
     * of associations in a Map, or the number of codeunits in a String, or the total number of
     * fields (positional and named) in a Record.
     *
     * Provided for instance kinds:
     *  - PlainInstance
     *  - String
     *  - List
     *  - Map
     *  - Set
     *  - Uint8ClampedList
     *  - Uint8List
     *  - Uint16List
     *  - Uint32List
     *  - Uint64List
     *  - Int8List
     *  - Int16List
     *  - Int32List
     *  - Int64List
     *  - Float32List
     *  - Float64List
     *  - Int32x4List
     *  - Float32x4List
     *  - Float64x2List
     *  - Record
     *
     * Can return <code>null</code>.
     */
    open fun getLength(): Int {
        return getAsInt("length")
    }


    /**
     * The parameterized class of a type parameter.
     *
     * Provided for instance kinds:
     *  - TypeParameter
     *
     * Can return <code>null</code>.
     */
    open fun getParameterizedClass(): ClassRef? {
        val obj = json.get("parameterizedClass")?.asJsonObject ?: return null
        val type = json.get("type")?.asString
        if ("Instance" == type || "@Instance" == type) {
            val kind = json.get("kind")?.asString
            if ("Null" == kind) return null
        }
        return ClassRef(obj)
    }

    /**
     * The list of parameter types for a function.
     *
     * Provided for instance kinds:
     *  - FunctionType
     *
     * Can return <code>null</code>.
     */
    open fun getParameters(): ElementList<Parameter>? {
        val parameters = json.get("parameters") ?: return null

        return object : ElementList<Parameter>(parameters.asJsonArray) {
            override fun basicGet(array: JsonArray, index: Int): Parameter {
                return Parameter(array.get(index).asJsonObject)
            }
        }
    }

    /**
     * The pattern of a RegExp instance.
     *
     * The pattern is always an instance of kind String.
     *
     * Provided for instance kinds:
     *  - RegExp
     *
     * Can return <code>null</code>.
     */
    open fun getPattern(): InstanceRef? {
        val obj = json.get("pattern")?.asJsonObject ?: return null
        return InstanceRef(obj)
    }

    /**
     * The port ID for a ReceivePort.
     *
     * Provided for instance kinds:
     *  - ReceivePort
     *
     * Can return <code>null</code>.
     */
    open fun getPortId(): Int {
        return getAsInt("portId")
    }

    /**
     * The return type of a function.
     *
     * Provided for instance kinds:
     *  - FunctionType
     *
     * Can return <code>null</code>.
     */
    open fun getReturnType(): InstanceRef? {
        val obj = json.get("returnType")?.asJsonObject ?: return null
        return InstanceRef(obj)
    }

    /**
     * The corresponding Class if this Type has a resolved typeClass.
     *
     * Provided for instance kinds:
     *  - Type
     *
     * Can return <code>null</code>.
     */
    open fun getTypeClass(): ClassRef? {
        val obj = json.get("typeClass")?.asJsonObject ?: return null
        val type = json.get("type")?.asString
        if ("Instance" == type || "@Instance" == type) {
            val kind = json.get("kind")?.asString
            if ("Null" == kind) return null
        }
        return ClassRef(obj)
    }

    /**
     * The type parameters for a function.
     *
     * Provided for instance kinds:
     *  - FunctionType
     *
     * Can return <code>null</code>.
     */
    open fun getTypeParameters(): ElementList<InstanceRef>? {
        val typeParameters = json.get("typeParameters") ?: return null

        return object : ElementList<InstanceRef>(typeParameters.asJsonArray) {
            override fun basicGet(array: JsonArray, index: Int): InstanceRef {
                return InstanceRef(array.get(index).asJsonObject)
            }
        }
    }

    /**
     * The value of this instance as a string.
     *
     * Provided for the instance kinds:
     *  - Null (null)
     *  - Bool (true or false)
     *  - Double (suitable for passing to Double.parse())
     *  - Int (suitable for passing to int.parse())
     *  - String (value may be truncated)
     *  - Float32x4
     *  - Float64x2
     *  - Int32x4
     *  - StackTrace
     *
     * Can return <code>null</code>.
     */
    open fun getValueAsString(): String? {
        return getAsString("valueAsString")
    }

    /**
     * The valueAsString for String references may be truncated. If so, this property is added with
     * the value 'true'.
     *
     * New code should use 'length' and 'count' instead.
     *
     * Can return <code>null</code>.
     */
    open fun getValueAsStringIsTruncated(): Boolean {
        val elem = json.get("valueAsStringIsTruncated")
        return elem?.asBoolean ?: false
    }

    /**
     * Returns whether this instance represents null.
     */
    open fun isNull(): Boolean {
        return getKind() == InstanceKind.Null
    }
}
